package com.zhangxun.aop;


import com.alibaba.fastjson.JSON;
import com.zhangxun.annotation.ShopLog;
import com.zhangxun.domain.SysLog;
import com.zhangxun.service.SysLogService;
import com.zhangxun.service.SysUserService;
import com.zhangxun.util.SecurityUtil;
import io.swagger.annotations.Api;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

@Api
@Aspect
@Component
public class LogAdvice {

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private SysLogService sysLogService;

    /**
     * 方法增强添加日志
     * @param joinPoint 连接点
     * @param shopLog 日志增强的注解
     * @return 返回方法执行结果
     */
    @Around("@annotation(shopLog)")
    public Object logAdvice(ProceedingJoinPoint joinPoint, ShopLog shopLog){
        Long userId = SecurityUtil.getUserId(); //获取用户id
        String userName = sysUserService.getById(userId).getUsername();//通过用户id查询数据库获得用户名
        String operation = shopLog.operation(); //通过注解获取本次的操作内容.
        String cName = joinPoint.getTarget().getClass().getName(); //获取完整类名
        String mName = joinPoint.getSignature().getName(); //获取方法名
        //拼接完整方法名
        String methodName = new StringBuilder(cName).append(".").append(mName).append("()").toString();

        String params = JSON.toJSONString(joinPoint.getArgs());//获取方法参数

        //通过请求对象获取请求的ip
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        String ip = request.getRemoteAddr();
        System.err.println(request.getRemoteHost());

        //获取方法执行之前时间
        Long startTime = System.currentTimeMillis();
        Object proceed = null;
        try {
            //执行方法
            proceed = joinPoint.proceed();
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }
        //获取方法执行结束时间
        Long endTime = System.currentTimeMillis();
        Long time = endTime-startTime;

        //通过上面获取的参数创建日志对象
        SysLog build = SysLog.builder()
                .username(userName)
                .operation(operation)
                .method(methodName)
                .params(params)
                .time(time)
                .ip(ip)
                .createDate(new Date())
                .build();
        //保存日志对象
        sysLogService.save(build);

        return proceed;
    }
}
